
package redis;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.util.Hashing;
import redis.clients.util.Sharded;

public class RedisPool
{

    private static Logger logger = Logger.getLogger(RedisPool.class);

    private static Map<String, ShardedJedisPool> POOL_CACHE = new Hashtable<String, ShardedJedisPool>(); // jedis���ӳ�

    private static RedisPool instance;

    private RedisPool()
    {

    }

    public static RedisPool getInstance()
    {

        if (instance == null)
        {
            instance = new RedisPool();
            initPool();
        }
        return instance;
    }

    /**
     * ��ʼ������
     */
    private static void initPool()
    {

        String source = PropertiesOperate.getRedisConfig("SOURCE");
        String sourceArr[] = source.split(",");
        for (int i = 0; i < sourceArr.length; i++)
        {
            logger.debug("��ʼ��Redis���ӳ�" + sourceArr[i]);
            String s = sourceArr[i];
            String HOST = PropertiesOperate.getRedisConfig("HOST_" + s);
            String PORT = PropertiesOperate.getRedisConfig("PORT_" + s);
            String PASSWORD = PropertiesOperate.getRedisConfig("PASSWORD_" + s);
            logger.debug("HOST=" + HOST + ";PORT=" + PORT + ";PASSWORD="
                         + PASSWORD);

            String[] hosts = HOST.split("\\;");
            String[] ports = PORT.split("\\;");
            String[] passwords = null;
            if (PASSWORD != null && PASSWORD.length() > 0)
            {
                passwords = PASSWORD.split("\\;");
            }
            List<JedisShardInfo> infos = new ArrayList<JedisShardInfo>();
            for (int j = 0; j < hosts.length; j++)
            {
                JedisShardInfo shardInfo = new JedisShardInfo(hosts[j],
                                                              Integer.parseInt(ports[j]));
                if (PASSWORD != null && PASSWORD.trim().length() > 0)
                {
                    if (passwords[j] != null && passwords[j].length() > 0)
                        shardInfo.setPassword(passwords[j]);
                }
                infos.add(shardInfo);
            }
            String MAXACTIVE = PropertiesOperate.getRedisConfig("MAXACTIVE");
            String MAXIDLE = PropertiesOperate.getRedisConfig("MAXIDLE");
            String MAXWAIT = PropertiesOperate.getRedisConfig("MAXWAIT");
            String isTestOnBorrow = PropertiesOperate.getRedisConfig("TESTONBORROW");
            JedisPoolConfig config = new JedisPoolConfig();
//            config.setMaxActive(Integer.parseInt(MAXACTIVE));
            config.setMaxIdle(Integer.parseInt(MAXIDLE));
//            config.setMaxWait(Integer.parseInt(MAXWAIT));
            config.setTestOnBorrow(Boolean.parseBoolean(isTestOnBorrow));
            config.setTestWhileIdle(Boolean.TRUE);
            ShardedJedisPool pool = new ShardedJedisPool(config,
                                                         infos,
                                                         Hashing.MURMUR_HASH,
                                                         Sharded.DEFAULT_KEY_TAG_PATTERN);

            POOL_CACHE.put(s, pool);
            System.out.println("Init Redis Pool " + sourceArr[i] + " Over");

        }
    }

    /**
     * ���redis����
     * 
     * @return
     */
    public ShardedJedis getSession(String source)
    {
        return POOL_CACHE.get(source).getResource();
    }

    /**
     * �ͷ�redis����
     * 
     * @param jedis
     */
    public void releaseSession(ShardedJedis jedis, String source)
    {
        if (POOL_CACHE.get(source) != null && jedis != null)
        {
            try
            {
                POOL_CACHE.get(source).returnResource(jedis);
            }
            catch (Exception e)
            {
                POOL_CACHE.get(source).returnBrokenResource(jedis);
            }
        }
    }
}
